﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace blackhouse.BlackApart.Business.Prices
{
    public class ImpApartmentPrice : IApartmentPrice
    {

        #region Fields

        private double price = 0;
        private double priceWithoutRabat = 0;
        private bool pricePrepared = false;
        private float rabat = 0;
        private List<IPriceRabat> priceRabats = new List<IPriceRabat>();

        private DateTime reservationFromDay = DateTime.MinValue;
        private DateTime reservationToDay = DateTime.MinValue;
        private int reservationNumberOfPeoples = 0;

        #endregion

        #region Properties

        public double InitialPrice { get; set; }

        public int ReservationNumberOfPeoples
        {
            get { return this.reservationNumberOfPeoples; }
            set
            {
                if (this.reservationNumberOfPeoples != value)
                {
                    this.pricePrepared = false;
                    this.reservationNumberOfPeoples = value;
                }
            }
        }

        public DateTime ReservationFromDay
        {
            get { return this.reservationFromDay; }
            set
            {
                if (this.reservationFromDay != value)
                {
                    this.pricePrepared = false;
                    this.reservationFromDay = value;
                }
            }
        }

        public DateTime ReservationToDay
        {
            get { return this.reservationToDay; }
            set
            {
                if (this.reservationToDay != value)
                {
                    this.pricePrepared = false;
                    this.reservationToDay = value;
                }
            }
        }

        public ApartmentPriceModifier[] Modifiers { get; private set; }

        #endregion

        #region Methods

        private void CheckForPreparePrices()
        {
            if (!this.pricePrepared)
            {
                this.PreparePrices();
                this.pricePrepared = true;
            }
        }

        private void PreparePrices()
        {

            this.price = 0;
            this.priceWithoutRabat = 0;

            foreach (ApartmentPriceModifier modifier in this.Modifiers)
            {
                modifier.ReservationFromDay = this.ReservationFromDay;
                modifier.ReservationNumberOfPeoples = this.ReservationNumberOfPeoples;
                modifier.ReservationToDay = this.ReservationToDay;
                modifier.Prepare();
            }
            SummaryPriceModifiers summary = new SummaryPriceModifiers();
            DateTime priceForDay = this.ReservationFromDay;
            while (priceForDay.Date < this.ReservationToDay.Date)
            {
                summary.Set(this.InitialPrice, priceForDay, this.Modifiers);
                this.price += summary.GetPrice();
                this.priceWithoutRabat += summary.GetPriceWithoutRabat();
                priceForDay = priceForDay.AddDays(1);
            }
            this.rabat = Convert.ToSingle(Math.Round(100d * (this.price / this.priceWithoutRabat - 1), 2));
        }

        public double GetPriceWithoutRabat()
        {
            this.CheckForPreparePrices();
            return this.priceWithoutRabat;
        }

        public double GetPrice()
        {
            this.CheckForPreparePrices();
            return this.price;
        }

        public float GetRabat()
        {
            this.CheckForPreparePrices();
            return this.rabat;
        }

        public void SetModifiers(IEnumerable<ApartmentPriceModifier> apartmentPriceModifier)
        {
            this.Modifiers = apartmentPriceModifier.ToArray();
            this.pricePrepared = false;
        }

        #endregion

    }
}
